package com.mti.utils;


import java.math.BigDecimal;
import java.text.DecimalFormat;

public class BitUtils {
    private static final int BITS_PER_UNIT = 8;
    private byte[] repn;
    private int length;

    private static int subscript(int idx) {
        return idx / BITS_PER_UNIT;
    }


    /**
     * 字符串转换成十六进制字符串
     *
     * @param str 待转换的ASCII字符串
     * @return String 每个Byte之间空格分隔，如: [61 6C 6B]
     */
    public static String str2HexStr(String str) {

        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;

        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            sb.append(' ');
        }
        return sb.toString().trim();
    }

    public static byte[] str2Hex(String string) {
        StringBuilder sb = new StringBuilder("");
        String[] bs = string.split(" ");
        byte[] bytes = new byte[bs.length];
        int i = 0;
        for (String s : bs) {
            if (s.length() == 1) {
                s = "0" + s;
            }
            bytes[i++] = hexStringTobyte(s);
        }
        return bytes;
    }

    public static String hexStr2Str(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;

        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes);
    }

    public static String bcd2Str(byte[] bytes) {
        StringBuffer temp = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
            temp.append((byte) (bytes[i] & 0x0f));
        }
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
                .toString().substring(1) : temp.toString();
    }

    /**
     * bytes转换成十六进制字符串
     *
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStrtrim(byte[] b) {
        String stmp = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }

    /**
     * bytes转换成十六进制字符串
     *
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStr(byte[] b) {
        String stmp = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
            sb.append("");
        }
        return sb.toString().toUpperCase().trim();
    }

    /**
     * 测站码转换BCD.
     * <p>
     * 方法添加日期（格式：YYYY-MM-DD）2015年8月17日 创建者:刘源
     *
     * @param
     * @return
     */
//    public static byte[] stationCode2Bcd(String stationCode) {
//        return Convert.str2BcdHigh(stationCode);
//    }
    public static byte[] hexStr2Bytes(String src) {
        int m = 0, n = 0;
        int l = src.length() / 2;
        byte[] ret = new byte[l];
        for (int i = 0; i < l; i++) {
            m = i * 2 + 1;
            n = m + 1;
            ret[i] = Byte.decode("0x" + src.substring(i * 2, m)
                    + src.substring(m, n));
        }
        return ret;
    }

    /**
     * String的字符串转换成unicode的String
     *
     * @param strText 全角字符串
     * @return String 每个unicode之间无分隔符
     * @throws Exception
     */
    public static String strToUnicode(String strText) throws Exception {
        char c;
        StringBuilder str = new StringBuilder();
        int intAsc;
        String strHex;
        for (int i = 0; i < strText.length(); i++) {
            c = strText.charAt(i);
            intAsc = (int) c;
            strHex = Integer.toHexString(intAsc);
            if (intAsc > 128)
                str.append("\\u" + strHex);
            else
                // 低位在前面补00
                str.append("\\u00" + strHex);
        }
        return str.toString();
    }

    /**
     * unicode的String转换成String的字符串
     *
     * @param hex 16进制值字符串 （一个unicode为2byte）
     * @return String 全角字符串
     */
    public static String unicodeToString(String hex) {
        int t = hex.length() / 6;
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < t; i++) {
            String s = hex.substring(i * 6, (i + 1) * 6);
            // 高位需要补上00再转
            String s1 = s.substring(2, 4) + "00";
            // 低位直接转
            String s2 = s.substring(4);
            // 将16进制的string转为int
            int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
            // 将int转换为字符
            char[] chars = Character.toChars(n);
            str.append(new String(chars));
        }
        return str.toString();
    }

    /**
     * int转换为byte[] 描述
     *
     * @param i
     * @return
     */
    public static byte[] intToByte(int i) {

        byte[] abyte0 = new byte[4];

        abyte0[0] = (byte) (0xff & i);

        abyte0[1] = (byte) ((0xff00 & i) >> 8);

        abyte0[2] = (byte) ((0xff0000 & i) >> 16);

        abyte0[3] = (byte) ((0xff000000 & i) >> 24);

        return abyte0;

    }

    public static int bytesToInt(byte[] bytes) {

        int addr = bytes[0] & 0xFF;

        addr |= ((bytes[1] << 8) & 0xFF00);
        addr |= ((bytes[2] << 16) & 0xff0000);
        addr |= ((bytes[3] << 24) & 0xff000000);

        return addr;

    }

    public static int bytesToInt4(byte[] bytes) {

        int addr = bytes[0] & 0xFF;

        addr |= ((bytes[1] << 8) & 0xFF00);

        return addr;

    }

    public static int bytesToInt2(byte[] bytes) {

        int addr = bytes[1] & 0xFF;

        addr |= ((bytes[0] << 8) & 0xFF00);

        return addr;

    }

    public static byte int2Onebyte(int i) {
        String istr = Integer.toHexString(i).length() == 1 ? "0" + Integer.toHexString(i) : Integer.toHexString(i);
        if (i <= 255 && i > -254) {
            return hexStringTobyte(istr);
        } else {
            return 0x0;
        }
    }

    public static int bytesToInt1(byte[] src, int offset) {
        int value;
        value = (int) (((src[offset] & 0xFF)) | (src[offset + 1] & 0xFF) << 8);
        return value;
    }

    public static byte[] String2Int(String str) {
        int i = str.length();
        byte[] b = new byte[i];
        for (int n = 0; n < i; n++) {
            // b[i] = Integer.toHexString(i).toUpperCase();
        }
        return b;
    }

    /**
     * 字符串转化为16进制ASCIIbyte[] 描述
     *
     * @param str
     * @return
     */
    public static byte[] StringTo16Ascii(String str) {// 字符串转换为ASCII码
        int i = str.length();
        byte[] b = new byte[i];
        char[] c = str.toCharArray();
        for (int n = 0; n < i; n++) {
            b[n] = (byte) c[n];
            b[n] = (byte) (b[n] & 0xFF);
        }
        return b;
    }

    /**
     * byte[]数组转化为十六进制字符串 描述
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv.toUpperCase() + " ");
        }

        return stringBuilder.substring(0, stringBuilder.length() - 1);
    }

    /**
     * Convert hex string to byte[]
     *
     * @param hexString the hex string
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    public static String byteToString(byte b) {
        String str = Integer.toHexString(b & 0xFF);
        String des = "";
        if (str.length() == 1) {
            des = "0" + str + "0";
        } else if (str.length() == 2) {
            des = str + "0";
        }

        return des;
    }


    public static String byteToStr(byte b) {
        return Integer.toHexString(b & 0xFF);
    }

    public static String strToString(String str) {
        String des = "";
        if (str.length() == 1) {
            des = "0" + str + "0";
        } else if (str.length() == 2) {
            des = str + "0";
        }

        return des;
    }

    /**
     * 字符串转byte 描述
     *
     * @param str
     * @return
     */
    public static byte hexStringTobyte(String str) {
        str = str.toUpperCase();
        char[] hexchars = str.toCharArray();
        byte b = (byte) (charToByte(hexchars[0]) << 4 | charToByte(hexchars[1]));
        return b;
    }

    /**
     * Convert char to byte
     *
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 将指定byte数组以16进制的形式打印到控制台 描述
     *
     * @param b
     */
    public static void printHexString(byte[] b) {
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            System.out.print(hex.toUpperCase());
        }

    }

    public static String bytes2HexString(byte[] b) {
        String ret = "";
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex + " ";
            }
            ret += hex.toUpperCase();
            ret += " ";
        }
        return ret;
    }

    /**
     * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序，和和intToBytes（）配套使用（两位byte)
     *
     * @param src    byte数组
     * @param offset 从数组的第offset位开始
     * @return int数值
     */
    public static int bytesToInt(byte[] src, int offset) {
        int value;
        value = (int) ((src[offset] & 0xFF) | ((src[offset + 1] & 0xFF) << 8));
        return value;
    }

    public static double bytesTofloat(byte[] src, int offset) {
        double value;
        value = (int) ((src[offset] & 0xFF) | ((src[offset + 1] & 0xFF) << 8));
        return value;
    }

    public static void main(String[] args) {
        DecimalFormat df = new DecimalFormat("0.00");
        byte[] b = new byte[2];
        b[0] = (byte) 0xFF;
        b[1] = (byte) 0x05;

        System.out.println(df.format(bytesTofloat(b, 0) / 100));

    }

    public static byte[] int2byte(int res) {
        byte[] targets = new byte[4];

        targets[0] = (byte) (res & 0xff);// 最低位
        targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
        targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
        targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
        return targets;
    }

    public static byte[] int2byte1(int res) {
        byte[] targets = new byte[2];
        targets[0] = (byte) (res & 0xff);// 最低位
        targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
        return targets;
    }

    public static byte[] intToByte1(int res) {
        byte[] targets = new byte[2];
        targets[0] = (byte) ((res & 0xff00) >> 8);// 高位
        targets[1] = (byte) ((res) & 0x00ff);// 低位
        return targets;
    }

    /**
     * 用于下行报文的报文正文的长度转换. (int转byte[])
     *
     * @param res
     * @return
     */
    public static byte[] int22byte(int res) {
        byte[] targets = new byte[2];
        targets[0] = (byte) ((res >> 8) | 0x80);// 高位
        targets[1] = (byte) (res & 0xff);// 低位
        return targets;
    }

    public static int byte2int(byte[] res) {
        // 一个byte数据左移24位变成0x??000000，再右移8位变成0x00??0000

        int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00) // | 表示安位或
                | ((res[2] << 24) >>> 8) | (res[3] << 24);
        return targets;
    }

    /**
     * byte数组中取int数值，本方法适用于(低位在后，高位在前)的顺序。和intToBytes2（）配套使用
     */
    public static int bytesToInt2(byte[] src, int offset) {
        int value;
        value = (int) (((src[offset] & 0xFF) << 8) | (src[offset + 1] & 0xFF));
        return value;
    }

    /**
     * bytes 转 long
     *
     * @param src
     * @return
     */
    public static int bytesToIntL(byte[] src) {
        int value;
        value = (src[3] & 0xFF)
                | ((src[2] & 0xFF) << 8)
                | ((src[1] & 0xFF) << 16)
                | ((src[0] & 0xFF) << 24);
        return value;
    }



    public static byte[] string2ASCII(String s) {// 字符串转换为ASCII码
        if (s == null || "".equals(s)) {
            return null;
        }

        char[] chars = s.toCharArray();
        byte[] asciiArray = new byte[chars.length];

        for (int i = 0; i < chars.length; i++) {
            asciiArray[i] = char2ASCII(chars[i]);
        }
        return asciiArray;
    }

    public static byte char2ASCII(char c) {
        return (byte) c;
    }

    public static String ascii2String(String ASCIIs) {
        String[] ASCIIss = ASCIIs.split(",");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < ASCIIss.length; i++) {
            sb.append((char) ascii2Char(Integer.parseInt(ASCIIss[i])));
        }
        return sb.toString();
    }

    public static char ascii2Char(int ASCII) {
        return (char) ASCII;
    }

    public static byte[] charToByte1(char c) {
        byte[] b = new byte[2];
        b[0] = (byte) ((c & 0xFF00) >> 8);
        b[1] = (byte) (c & 0xFF);
        return b;
    }

    public static float getPower(int x, int y) {
        if (y == 0)
            return 1;
        if (y == 1)
            return x;
        return x * getPower(x, y - 1);
    }

    public static int getDataLen(byte b) {
        int len = (b & 0xF8) >> 3;
        return len;
    }

    public static int getDecimalDigits(byte b) {
        return b & 0x07;
    }


    public static double retainDecimal(double value, int bit) {

        BigDecimal b = new BigDecimal(value);
        value = b.setScale(bit, BigDecimal.ROUND_HALF_UP).doubleValue();
        return value;
    }

    public static byte lengthConversion(int i) {
        return (byte) (i << 3);
    }


    public static int subArrayIndex(byte[] parent, byte[] child) {
        int result = -1;
        for (int i = 0; i < parent.length - 1; i++) {
            if (parent[i] == child[0] && parent[i + 1] == child[1]) {
                result = i;
                break;
            }

        }
        return result;
    }
}
